/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.cliente.asteroide.vista;

import co.com.entities.Asteroide;
import co.com.entities.ClasificacionAsteroide;
import co.com.entities.Unidaddistancia;
import co.com.client.BaseView.CreateBase;
import co.com.cliente.Services;
import co.com.cliente.asteroide.estuctura.AsteroideDS;
import co.com.cliente.asteroide.estuctura.AsteroideRecord;
import co.com.cliente.clasificacionAsteroide.estructura.ClasificacionAsteroideDS;
import co.com.cliente.clasificacionAsteroide.estructura.ClasificacionAsteroideRecord;
import co.com.cliente.unidadDistancia.estructura.UnidadDistanciaDS;
import co.com.cliente.unidadDistancia.estructura.UnidadDistanciaRecord;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.SelectionAppearance;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.RecordDoubleClickEvent;
import com.smartgwt.client.widgets.grid.events.RecordDoubleClickHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author dloaiza
 */
public class AsteroideEdition extends CreateBase {

    private Asteroide asteroide;
    private HLayout accionesAsteroide;
    private DynamicForm frmAsteroideEdition;
    private TextItem txtNombre, txtRadio, txtDistanciaReal, txtOrbitaReal;
    private Button btnGuardar, btnLimpiar, btnEliminar;
    private SelectItem cbxClasificacion, cbxUnidadDistancia;
    private ListGrid asteroideGrid;
    private ClasificacionAsteroideDS clasificacionDS;
    private UnidadDistanciaDS unidadDistanciaDS;

    public AsteroideEdition() {
        super("Asteroides", "100%");
        initComponents();
    }

    private void initComponents() {

        clasificacionDS = new ClasificacionAsteroideDS();
        unidadDistanciaDS = new UnidadDistanciaDS();
       
        txtNombre = new TextItem();
        txtNombre.setTitle("Nombre");
        txtNombre.setWidth(200);
        txtNombre.setRequired(true);
        txtNombre.setName("txtNombre");
        txtNombre.setLength(210);
        txtNombre.setAlign(Alignment.LEFT);
        txtNombre.setWrapTitle(false);

        txtRadio = new TextItem();
        txtRadio.setTitle("Radio");
        txtRadio.setWidth(200);
        txtRadio.setRequired(true);
        txtRadio.setName("txtRadio");
        txtRadio.setAlign(Alignment.LEFT);
        txtRadio.setWrapTitle(false);

        txtDistanciaReal = new TextItem();
        txtDistanciaReal.setTitle("Distancia real al sol");
        txtDistanciaReal.setWidth(200);
        txtDistanciaReal.setRequired(true);
        txtDistanciaReal.setName("txtDistanciaReal");
        txtDistanciaReal.setAlign(Alignment.LEFT);
        txtDistanciaReal.setWrapTitle(false);
        
        txtOrbitaReal = new TextItem();
        txtOrbitaReal.setTitle("Orbita real al sol");
        txtOrbitaReal.setWidth(200);
        txtOrbitaReal.setRequired(true);
        txtOrbitaReal.setName("txtOrbitaReal");
        txtOrbitaReal.setAlign(Alignment.LEFT);
        txtOrbitaReal.setWrapTitle(false);
        
        asteroideGrid = new ListGrid();
        asteroideGrid.setWidth100();
        asteroideGrid.setHeight100();
        asteroideGrid.setFields(AsteroideRecord.getFields());
        asteroideGrid.setEmptyMessage("No hay registros para mostrar");
        asteroideGrid.setSelectionType(SelectionStyle.SIMPLE);
        asteroideGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX);
        asteroideGrid.setFilterOnKeypress(true);
        asteroideGrid.setShowFilterEditor(true);
        asteroideGrid.addRecordDoubleClickHandler(new RecordDoubleClickHandler() {
            @Override
            public void onRecordDoubleClick(RecordDoubleClickEvent event) {
                asteroide = (Asteroide) event.getRecord().getAttributeAsObject("asteroideData");
                cbxClasificacion.setValue(asteroide.getNmidClasificacion().getDsdescripcion());
                cbxUnidadDistancia.setValue(asteroide.getUnidadMedida().getDsunidad());
                txtDistanciaReal.setValue(asteroide.getDistanciaSolReal());
                txtOrbitaReal.setValue(asteroide.getOrbitaReal());
                txtNombre.setValue(asteroide.getDsnombre());
                txtRadio.setValue(asteroide.getNmradio());
            }
        });
        asteroideGrid.setDataSource(new AsteroideDS());
        asteroideGrid.setAutoFetchData(true);
        

        btnGuardar = new Button("Guardar");

        btnLimpiar = new Button("Limpiar");
        
        btnEliminar = new Button("Eliminar");
        

        cbxClasificacion = new SelectItem();
        cbxClasificacion.setTitle("Clasificación");
        cbxClasificacion.setName("cbxClasificacion");
        cbxClasificacion.setRequired(true);
        cbxClasificacion.setWidth(200);
        cbxClasificacion.setDisplayField(ClasificacionAsteroideDS.DESCRIPCION);
        cbxClasificacion.setValueField(ClasificacionAsteroideDS.DESCRIPCION);
        cbxClasificacion.setAlign(Alignment.LEFT);
        cbxClasificacion.setWrapTitle(false);
        
        cbxUnidadDistancia = new SelectItem();
        cbxUnidadDistancia.setTitle("Unidad de distancia");
        cbxUnidadDistancia.setName("cbxUnidadDistancia");
        cbxUnidadDistancia.setRequired(true);
        cbxUnidadDistancia.setWidth(200);
        cbxUnidadDistancia.setDisplayField(UnidadDistanciaDS.DSUNIDAD);
        cbxUnidadDistancia.setValueField(UnidadDistanciaDS.DSUNIDAD);
        cbxUnidadDistancia.setAlign(Alignment.LEFT);
        cbxUnidadDistancia.setWrapTitle(false);
        
        accionesAsteroide = new HLayout();
        accionesAsteroide.setMargin(20);
        accionesAsteroide.setMembersMargin(20);
        accionesAsteroide.setHeight(50);
        accionesAsteroide.setWidth("100%");
        accionesAsteroide.setAlign(Alignment.CENTER);
        accionesAsteroide.setMembers(btnGuardar, btnLimpiar, btnEliminar);

        frmAsteroideEdition = new DynamicForm();
        frmAsteroideEdition.setNumCols(4);
        frmAsteroideEdition.setItems(txtNombre, txtRadio, txtDistanciaReal, cbxUnidadDistancia, txtOrbitaReal, cbxClasificacion);

        AddActionBarItem(accionesAsteroide);
        
        
        VLayout contenedor = new VLayout();
        contenedor.setMembers(frmAsteroideEdition, asteroideGrid);
        AddFormContainerItem(contenedor);

        btnGuardar.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                if (frmAsteroideEdition.validate()) {
                    if(asteroide==null){
                        Services.getAsteroideServices().guardarAsteroide(getAsteroide(), new AsyncCallback<Void>() {

                        public void onFailure(Throwable caught) {
                            SC.say("Error en creación de asteroides");
                            asteroide = null;
                        }

                        public void onSuccess(Void result) {
                            SC.say("Creación asteroide", "Señor usuario, el asteroide fue registrado correctamente");
                            asteroideLoad();
                            asteroide = null;
                        }
                    });
                    }
                    else{
                        Services.getAsteroideServices().actualizarAsteroide(getAsteroide(), new AsyncCallback<Void>() {

                            public void onFailure(Throwable caught) {
                                SC.say("Error en actualización de asteroides");
                                asteroide = null;
                            }

                            public void onSuccess(Void result) {
                                SC.say("Actualización asteroide", "Señor usuario, el asteroide fue actualizado correctamente");
                                asteroideLoad();
                                asteroide = null;
                            }
                        });
                    }
                    
                }
            }
        });
        btnLimpiar.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                frmAsteroideEdition.clearValues();
                asteroide = null;
            }
        });
        
        btnEliminar.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                ListGridRecord[] selectedRecords = asteroideGrid.getSelection();
                final List<Asteroide> asteroidesToDelete = new ArrayList<Asteroide>(selectedRecords.length);


                for (ListGridRecord rec : selectedRecords) {
                    asteroidesToDelete.add((Asteroide) rec.getAttributeAsObject("asteroideData"));
                }
                if (asteroidesToDelete.isEmpty()) {

                    SC.warn("Debe seleccionar al menos un asteroide para poder eliminar");
                    return;
                } else {
                    SC.confirm("Confirmar Eliminación", "¿Esta seguro que desea eliminar los asteroides seleccionados?", new BooleanCallback() {

                        @Override
                        public void execute(Boolean value) {
                            if (value) {
                                AsyncCallback<Void> updateStateCallback = new AsyncCallback<Void>() {

                                    @Override
                                    public void onFailure(Throwable caught) {
                                        Logger.getLogger(getClass().getName()).log(Level.INFO, "Mensaje informativo... no se pudo eliminar el producto debido a: " + caught.getMessage());
                                        SC.say("Eliminación de asteroides", caught.getMessage());
                                    }

                                    @Override
                                    public void onSuccess(Void result) {
                                        SC.say("Eliminación de asteroides", "Señor usuario, el(los) asteroide(s) se han eliminado correctamente");
                                        asteroideLoad();
                                    }
                                };
                                Services.getAsteroideServices().eliminarAsteroides(asteroidesToDelete, updateStateCallback);
                            }
                        }
                    });
                }
            }
        });
        
        cargarClasificacion();
        cargarUnidad();
        asteroideLoad();
    }
    
    private void asteroideLoad(){
        Services.getAsteroideServices().consultarAsteroides(new AsyncCallback<List<Asteroide>>() {

            public void onFailure(Throwable caught) {
                caught.getMessage();
            }

            public void onSuccess(List<Asteroide> result) {
               clearResults();
                for (int i = 0; i < result.size(); i++) {
                    asteroideGrid.addData(new AsteroideRecord(result.get(i)));
                }
            }
        });
    }
    
    private void clearResults() {
        ListGridRecord[] records = asteroideGrid.getRecords();
        if (records.length > 0) {
            for (int i = 0; i < records.length; i++) {
                asteroideGrid.removeData(records[i]);
            }
        }
    }
    
    public Asteroide getAsteroide(){
        if(asteroide==null){
            asteroide = new Asteroide();
        }
        ClasificacionAsteroide clasificacion = cbxClasificacion.getSelectedRecord().getAttributeAsObject("ClasificacionAsteroide")==null?null:(ClasificacionAsteroide) cbxClasificacion.getSelectedRecord().getAttributeAsObject("ClasificacionAsteroide");
        Unidaddistancia unidadDistnacia = cbxUnidadDistancia.getSelectedRecord().getAttributeAsObject("UnidadDistancia")==null?null:(Unidaddistancia) cbxUnidadDistancia.getSelectedRecord().getAttributeAsObject("UnidadDistancia");
        asteroide.setUnidadMedida(unidadDistnacia);
        asteroide.setDistanciaSolReal(txtDistanciaReal.getValueAsString()==null?0D:Double.parseDouble(txtDistanciaReal.getValueAsString()));
        asteroide.setOrbitaReal(txtOrbitaReal.getValueAsString()==null?0D:Double.parseDouble(txtOrbitaReal.getValueAsString()));
        asteroide.setNmidClasificacion(clasificacion);
        asteroide.setDsnombre(txtNombre.getValueAsString());
        asteroide.setNmradio(txtRadio.getValueAsString()==null?0D:Double.parseDouble(txtRadio.getValueAsString()));
        
        return asteroide;
    }
    
    public void cargarUnidad() {
        Services.getUnidadDistanciaServices().consultarUnidades(new AsyncCallback<List<Unidaddistancia>>() {

            public void onFailure(Throwable caught) {
                
            }

            public void onSuccess(List<Unidaddistancia> unidades) {

                for (int i = 0; i < unidades.size(); i++) {
                    unidadDistanciaDS.addData(new UnidadDistanciaRecord(unidades.get(i)));
                }
                cbxUnidadDistancia.setOptionDataSource(unidadDistanciaDS);
            }
        });
    }
    
    public void cargarClasificacion() {
        Services.getClasificacionAsteroideServices().consultarClasificacionAsteroides(new AsyncCallback<List<ClasificacionAsteroide>>() {

            public void onFailure(Throwable caught) {
                
            }

            public void onSuccess(List<ClasificacionAsteroide> clasificacion) {

                for (int i = 0; i < clasificacion.size(); i++) {
                    clasificacionDS.addData(new ClasificacionAsteroideRecord(clasificacion.get(i)));
                }
                cbxClasificacion.setOptionDataSource(clasificacionDS);
            }
        });
    }
}